home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Glue to call ServerDispatch from a PowerPC application
- **
- ** by Jim Luther, Apple Developer Technical Support
- **
- ** File: SyncServerDispatch.c
- **
- ** Copyright © 1995 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
- */
-
- #include <Types.h>
- #include <MixedMode.h>
- #include <Errors.h>
- #include <Traps.h>
-
- #include "ServerControlIntf.h"
-
- /*
- ** The function calling convention ServerDispatchProc
- */
- typedef pascal OSErr (*ServerDispatchProcPtr)(long dZero, SCParamBlockPtr thePB);
-
- typedef UniversalProcPtr ServerDispatchProcUPP;
-
- /*
- ** Procedure information for ServerDispatchProc function
- */
- enum
- {
- uppServerDispatchProcInfo = kRegisterBased
- | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long)))
- | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(sizeof(long)))
- | REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(SCParamBlockPtr)))
- };
-
- /*
- ** The CallServerDispatchProc macro calls ServerDispatch
- ** using uppServerDispatchProcInfo defined above.
- **
- ** Notes:
- ** ServerDispatch expects register D0 to always be 0 on input, so the
- ** dZero parameter (the first parameter) is always 0.
- **
- ** Not all versions of Macintosh File Sharing return a result in
- ** register D0, so we don't bother to get the value in D0. Instead, the
- ** SyncServerDispatch glue code (below) returns the result from the
- ** parameter block's ioResult field.
- */
- #define CallServerDispatchProc(userRoutine, thePB) \
- CallOSTrapUniversalProc((UniversalProcPtr)(userRoutine), uppServerDispatchProcInfo, ServerDispatch, 0, (thePB))
-
- /*****************************************************************************/
-
- /*
- ** A concise version of TrapAvailable function.
- ** (another effort in the quest for smaller, faster code)
- */
- static Boolean TrapAvailable(short theTrap)
- {
- TrapType tType;
- short numToolboxTraps;
-
- /* Get the trap type */
- if ( (theTrap & 0x0800) > 0 )
- tType = ToolTrap;
- else
- tType = OSTrap;
-
- /* If theTrap is ToolTrap, see if it is in the trap table */
- if ( tType == ToolTrap )
- {
- /* Get the number of toolbox traps */
- if ( NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap) )
- numToolboxTraps = 0x200;
- else
- numToolboxTraps = 0x400;
-
- /* Is theTrap in the trap table? */
- if ( (theTrap & 0x07ff) >= numToolboxTraps )
- theTrap = _Unimplemented; /* No, make it _Unimplemented */
- }
-
- /* Trap is available if it doesn't equal _Unimplemented */
- return ( NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap) );
- }
-
- /*****************************************************************************/
-
- /*
- ** SyncServerDispatch is the glue code to call the ServerDispatch trap
- ** from PowerPC code.
- */
- pascal OSErr SyncServerDispatch(SCParamBlockPtr PBPtr)
- {
- /*
- ** Keep the address of ServerDispatch in a static so we don't
- ** have to check for ServerDispatch and get its address
- ** every time SyncServerDispatch is called.
- */
- static ServerDispatchProcUPP serverDispatchAddress = NULL;
-
- /* If serverDispatchAddress is uninitialized, try to initialize it */
- if ( serverDispatchAddress == NULL )
- {
- /* Make sure ServerDispatch is available (just in case someone didn't check for it first) */
- if ( TrapAvailable(ServerDispatch) )
- {
- /* Get the address of ServerDispatch */
- serverDispatchAddress = (ServerDispatchProcUPP)NGetTrapAddress(ServerDispatch, OSTrap);
- }
- }
-
- /* If serverDispatchAddress was initialized */
- if ( serverDispatchAddress != NULL )
- {
- /* Call ServerDispatch and return the result from ioResult */
- (void) CallServerDispatchProc(serverDispatchAddress, PBPtr);
- return ( PBPtr->startPB.ioResult );
- }
- else
- {
- /* Return an error to indicate ServerDispatch wasn't available */
- return ( paramErr );
- }
- }
-
- /*****************************************************************************/
-